package cn.wind.xboot.module.app.v1.controller;

import cn.wind.xboot.core.res.ApiResult;
import cn.wind.xboot.logic.app.entity.AppFeedback;
import cn.wind.xboot.logic.app.service.IAppFeedbackService;
import cn.wind.klog.annotation.Log;
import cn.wind.klog.annotation.LogAround;
import cn.wind.klog.annotation.LogFilterType;
import cn.wind.xboot.conf.config.XbootConfiguration;
import cn.wind.xboot.core.utils.*;
import cn.wind.xboot.framework.constant.ActionConstant;
import cn.wind.xboot.framework.constant.ChannelConstant;
import cn.wind.xboot.framework.constant.ModuleConstant;
import cn.wind.xboot.framework.domain.PageVo;
import cn.wind.xboot.logic.cli.entity.*;
import cn.wind.xboot.logic.cli.service.*;
import cn.wind.xboot.module.app.v1.handler.AppMyLogHandler;
import cn.wind.xboot.module.app.v1.vo.CliInfoVo;
import cn.wind.xboot.module.app.v1.vo.CliLogVo;
import cn.wind.xboot.module.web.service.UploadService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Sets;
import com.wind.encrypt.anno.EnRequestBody;
import com.wind.encrypt.anno.Encrypt;
import com.wind.encrypt.anno.Secure;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.provider.token.ConsumerTokenServices;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * <p>Title: LoginController</p>
 * <p>Description: TODO</p>
 *
 * @author xukk
 * @version 1.0
 * @date 2018/8/7
 */
@RestController
@RequestMapping("api/user")
@Secure(encrypt = @Encrypt(ignore = true))
public class AppUserController extends BaseController {
    @Autowired
    private ICliPushService cliPushService;
    @Autowired
    private ICliInfoService cliInfoService;
    @Autowired
    private ConsumerTokenServices consumerTokenServices;
    @Autowired
    private ICliClientService cliClientService;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private XbootConfiguration xbootConfiguration;
    @Autowired
    private ICliLogService cliLogService;
    @Autowired
    private IAppFeedbackService appFeedbackService;

    @DeleteMapping(value = "logout")
    public ApiResult logout(@RequestHeader("Authorization") String authorization) throws Exception {
        String accessToken = authorization.replace("Bearer", "").trim();
        consumerTokenServices.revokeToken(accessToken);
        return ApiResult.Custom().success();
    }

    @PostMapping(value = "refresh")
    public ApiResult refresh(@RequestBody JSONObject jsonObject, HttpServletRequest request) throws Exception {
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Authorization", "Basic YXBwOmFwcA==");
        //  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("refresh_token", jsonObject.getString("refreshToken"));
        params.add("scope", "app");
        params.add("grant_type", "refresh_token");
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, headers);
        ResponseEntity responseEntity = restTemplate.postForEntity(RequestUtil.getBasePath(request)+ "/oauth/token", requestEntity, Map.class);
        return ApiResult.Custom().success().add(JSONObject.parseObject(JsonUtil.toJson(responseEntity.getBody())));
    }

    @PostMapping(value = "push")
    public ApiResult push(@RequestBody JSONObject jsonObject) {
        hasNoBlank(jsonObject, Sets.newHashSet("platform", "deviceId"));
        String platform = jsonObject.getString("platform");
        String deviceId = jsonObject.getString("deviceId");
        Long userId = UserUtil.currentUserId();
        CliPush cliPush = new CliPush();
        cliPush.setDeviceId(deviceId);
        cliPush.setPlatform(platform);
        cliPush.setCliId(userId);
        cliPushService.saveCliPush(cliPush, new QueryWrapper<CliPush>().lambda().eq(CliPush::getCliId, userId).eq(CliPush::getPlatform, platform));
        return ApiResult.Custom().success();
    }

    @LogAround
    @Log(module = ModuleConstant.USER, action = ActionConstant.INFO, channel = ChannelConstant.APP, pattern = "获取用户信息", filterType = LogFilterType.ASPECTJ, fallback = AppMyLogHandler.class)
    @GetMapping(value = "info")
    public ApiResult info() {
        CliInfo cliInfo = cliInfoService.getOne(new QueryWrapper<CliInfo>()
                .lambda()
                .eq(CliInfo::getCliId, UserUtil.currentUserId()));
        CliInfoVo cliInfoVo = beanMapper.map(cliInfo, CliInfoVo.class);
        return ApiResult.Custom().success().add(cliInfoVo);
    }

 /*   @PatchMapping(value = "info")
    public ApiResult modify(@RequestBody JSONObject jsonObject) {
        hasNoBlank(jsonObject, Sets.newHashSet("type"));
        String type = jsonObject.getString("type");
        Long cliId = UserUtil.currentUserId();
        LambdaQueryWrapper ew = new QueryWrapper<CliInfo>().lambda().eq(CliInfo::getCliId, cliId);
        CliInfo cliInfo = new CliInfo();
        switch (type) {
            case "nickName":
                //修改昵称
                hasNoBlank(jsonObject, Sets.newHashSet("nickName"));
                String nickName = jsonObject.getString("nickName");
                cliInfo.setNickName(nickName);
                return modifyBoolean(cliInfoService.update(cliInfo, ew));
            case "password":
                //修改密码
                hasNoBlank(jsonObject, Sets.newHashSet("origPassword", "newPassword"));
                String origPassword = jsonObject.getString("origPassword");
                String newPassword = jsonObject.getString("newPassword");
                CliClient cliClient = cliClientService.getById(cliId);
                Assert.checkArgument(cliClient != null, "对象不存在");
                if (PasswordUtil.matches(origPassword, cliClient.getPassword())) {
                    return modifyBoolean(cliClientService.updatePassword(cliId, PasswordUtil.encode(newPassword)));
                } else {
                    return ApiResult.Custom().failure("密码不一致");
                }
            case "mobile":
                hasNoBlank(jsonObject, Sets.newHashSet("mobile", "smsCode"));
                String mobile = jsonObject.getString("mobile");
                String smsCode = jsonObject.getString("smsCode");
                smsHelper.checkCode(mobile, smsCode);
                cliInfo.setMobile(mobile);
                return modifyBoolean(cliInfoService.updateMobile(cliId, mobile));
            default:
                break;
        }*/
   /*     return ApiResult.Custom().failure();
    }*/

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "文件上传")
    public ApiResult upload(String type, MultipartFile[] file) {
        try {
            Long cliId = UserUtil.currentUserId();
            LambdaQueryWrapper ew = new QueryWrapper<CliInfo>().lambda().eq(CliInfo::getCliId, cliId);
            String ROOT = xbootConfiguration.getUpload().getAuthRoot();
            List<String> list = uploadService.fileUpload(file, ROOT);
            switch (type) {
                case "avatar":
                    if (list.size() == 0) {
                        return ApiResult.Custom().failure("修改头像失败");
                    }
                    String uploadPath = list.get(0);
                    CliInfo cliInfo = new CliInfo();
                    cliInfo.setAvatar(uploadPath);
                    return ApiResult.Custom(cliInfoService.update(cliInfo, ew), "修改头像成功", "修改头像失败");
                default:
                    return ApiResult.Custom().failure("缺少type");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ApiResult.Custom().failure("上传失败");
    }

    @PostMapping(value = "feedback")
    public ApiResult feedback(String title, String suggestions, String email, MultipartFile[] file) {
        try {
            AppFeedback appFeedback = new AppFeedback();
            appFeedback.setTitle(title);
            appFeedback.setSuggestions(suggestions);
            Long cliId = UserUtil.currentUserId();
            appFeedback.setCliId(cliId);
            appFeedback.setEmail(email);
            if (file != null && file.length > 0) {
                String ROOT = xbootConfiguration.getUpload().getAuthRoot();
                List<String> list = uploadService.fileUpload(file, ROOT);
                appFeedback.setPhoto(JSONObject.toJSONString(list));
            }
            return ApiResult.Custom(appFeedbackService.save(appFeedback), "提交成功", "提交失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ApiResult.Custom().failure("提交失败");
    }

    @GetMapping(value = "signHistory")
    public ApiResult signHistory(@EnRequestBody String data) {
        JSONObject jsonObject=JSONObject.parseObject(data);
        PageVo pageVo = new PageVo();
        pageVo.init(jsonObject);

        IPage page = cliLogService.page(pageVo.init(),
                new QueryWrapper<CliLog>().lambda()
                        .eq(CliLog::getChannel, ChannelConstant.APP)
                        .eq(CliLog::getModule, ModuleConstant.USER)
                        .in(CliLog::getAction, ActionConstant.LOGIN)
                        .eq(CliLog::getUsername, UserUtil.currentUserId())
                        .orderByDesc(CliLog::getCreateTime));
        page.setRecords(mapList(page.getRecords(), CliLogVo.class));
        return ApiResult.Custom().success().add(page);
    }
    @Autowired
    private ICliDeviceLogService cliDeviceLogService;

    @PostMapping(value = "deviceLog")
    public ApiResult saveDeviceLog(@RequestBody JSONObject jsonObject){
        hasNoBlank(jsonObject,Sets.newHashSet("deviceNo","operationScene","type"));
        String deviceNo=jsonObject.getString("deviceNo");
        String operationScene=jsonObject.getString("operationScene");
        String operationDeviceNo=jsonObject.getString("operationDeviceNo");
        String type=jsonObject.getString("type");
        Assert.checkArgument("ADD".equals(type)||"DELETE".equals(type),"type类型不对");
        CliDeviceLog cliDeviceLog=new CliDeviceLog();
        cliDeviceLog.setCliId(UserUtil.currentUserId());
        cliDeviceLog.setDeviceNo(deviceNo);
        cliDeviceLog.setType(type);
        cliDeviceLog.setOperationScene(operationScene);
        cliDeviceLog.setOperationDeviceNo(operationDeviceNo);
        return ApiResult.Custom(cliDeviceLogService.save(cliDeviceLog));
    }
    @GetMapping(value="deviceLog")
    public ApiResult getDeviceLog(@EnRequestBody String data){
        JSONObject jsonObject=JSONObject.parseObject(data);
        PageVo pageVo = new PageVo();
        pageVo.init(jsonObject);
        return ApiResult.Custom().success().add(cliDeviceLogService.page(pageVo.init(),
                new QueryWrapper<CliDeviceLog>().lambda().eq(CliDeviceLog::getCliId, UserUtil.currentUserId())));
    }
}
